home *** CD-ROM | disk | FTP | other *** search
- /* ringd.c by Adam Dace <thekind@tezcat.com>
- Enjoy... */
-
- #include <errno.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <syslog.h>
- #include <termios.h>
- #include <time.h>
- #include <unistd.h>
- #include <sys/file.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <sys/wait.h>
- #include "config.h"
-
- int tty_open(void);
- int modem_reset(void);
- int get_rings(int);
- void shut_down(int);
-
- int fd_modem, rings=0;
- char buf[32];
- time_t timer1;
-
- int main(void)
- {
- int got_rings;
- pid_t pid;
-
- if ((pid = fork()) < 0)
- {
- perror("Couldn't fork() daemon process");
- return(-1);
- }
- else
- if (pid != 0)
- exit(0);
-
- /* From here on out, it's daemon all the way... */
-
- setsid();
- chdir("/");
- umask(0);
- close(STDIN_FILENO);
- close(STDOUT_FILENO);
- close(STDERR_FILENO);
-
- if (signal(SIGTERM, shut_down) == SIG_ERR)
- {
- syslog(LOG_ERR,strerror(errno));
- shut_down(-1);
- }
-
- openlog("ringd", LOG_PID, LOG_DAEMON);
- syslog(LOG_NOTICE, "ringd 0.8 monitoring modem");
-
- while (1)
- {
- got_rings = 0;
-
- while (tty_open() < 0)
- {
- close (fd_modem);
- sleep (RECYCLE_TIME);
- }
-
- if (modem_reset() < 0)
- shut_down(-1);
-
- while (!got_rings)
- {
- timer1 = 0;
- time(&timer1);
-
- if (get_rings(3) < 0)
- {
- rings=1;
- continue;
- }
- else
- rings=0;
-
- if (get_rings(2) < 0)
- {
- rings=1;
- continue;
- }
- else
- rings=0;
-
- got_rings=1;
- }
-
- if (close(fd_modem) < 0)
- {
- syslog(LOG_ERR,strerror(errno));
- shut_down(-1);
- }
-
- sleep(2);
-
- if ((pid=fork()) < 0) /* Be a man and fork, he says... */
- { /* What utter crap and pain. */
- syslog(LOG_ERR,strerror(errno));
- shut_down(-1);
- }
- else
- if (pid == 0)
- execl(PROGRAM,PROGRAM,ARG,NULL);
- else
- wait(NULL);
-
- sleep(2);
- }
- }
-
-
- int tty_open(void) /* Opens the modem, and sets terminal attributes. */
- {
- struct termios term;
-
- if ((fd_modem = open("/dev/modem", O_RDWR | O_NOCTTY)) < 0)
- {
- syslog(LOG_ERR,strerror(errno));
- shut_down(-1);
- }
-
- if (isatty(fd_modem) == 0)
- {
- syslog(LOG_ERR,strerror(errno));
- shut_down(-1);
- }
-
- if (flock(fd_modem,LOCK_EX) < 0)
- {
- syslog(LOG_ERR,strerror(errno));
- shut_down(-1);
- }
-
- /* This right here is such a hack, even I have a hard time believing
- * it. I stole these values from kermit and stty -a. I tried a
- * number of other combinations, which didn't work, some help here
- * would be greatly appreciated. */
-
- term.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
- term.c_iflag = IGNBRK | IGNPAR;
- term.c_lflag = 0;
- term.c_oflag = 0;
-
- if (cfsetispeed(&term,BPS_RATE) < 0)
- return(-1);
- if (cfsetospeed(&term,BPS_RATE) < 0)
- return(-1);
-
- if (tcsetattr(fd_modem, TCSANOW, &term) < 0)
- return(-1);
-
- return(0);
- }
-
- int modem_reset(void) /* Resets the modem, and checks for additional rings. */
- {
- char command[]=RESET_STR; /* Modem reset. */
- int number;
-
- if (write(fd_modem, &command, 4) < 0)
- {
- syslog(LOG_ERR,strerror(errno));
- shut_down(-1);
- }
-
- sleep(RING_TIME);
-
- number=read(fd_modem, &buf, 32);
- buf[number]='\0';
-
- if (strstr(buf, OK) == NULL)
- {
- syslog(LOG_ERR,strerror(errno));
- shut_down(-1);
- }
-
- if (strstr(buf, RING) != NULL )
- return (1);
-
- return (0);
- }
-
- int get_rings(int rings_wanted) /* Waits for a number of specified rings. */
- {
- int counter=0, done=0;
- time_t time1=0, time2=0;
- fd_set myset;
-
- FD_ZERO(&myset);
-
- while (!done) /* BTW, read() is slightly broken, so select() we go */
- {
- FD_SET(fd_modem, &myset);
- select(2,&myset,NULL,&myset,NULL);
-
- counter = read(fd_modem, &buf, 256);
- buf[counter]='\0';
-
- if ((counter > 0) && (strstr(buf, RING) != NULL))
- {
- time(&time1);
-
- if ((time2 == 0) && ((abs(difftime(timer1, time1)) < TOTAL_TIME)))
- {
- rings++;
- time2 = time1;
- }
- else
- {
- if (((abs(difftime(time1, time2))) < RING_TIME) &&
- ((abs(difftime(timer1, time2))) < TOTAL_TIME))
- {
- rings++;
- time2 = time1;
- }
- else
- return(-1);
- }
- }
-
- if (rings == rings_wanted)
- {
- if (modem_reset() == 0)
- done=1;
- else
- return(-1);
- }
- }
-
- return(0);
- }
-
- void shut_down(int status) /* Shut down somewhat gracefully. */
- {
- if (status != SIGTERM)
- syslog(LOG_NOTICE,"internal error occured, shutting down");
- else
- syslog(LOG_NOTICE,"SIGTERM recieved, shutting down");
-
- closelog();
- flock(fd_modem,LOCK_UN);
- close(fd_modem);
- exit(status);
- }
-